home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / include / nss / pk11pars.h < prev    next >
C/C++ Source or Header  |  2006-04-20  |  22KB  |  870 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is the Netscape security libraries.
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  * Netscape Communications Corporation.
  18.  * Portions created by the Initial Developer are Copyright (C) 2001
  19.  * the Initial Developer. All Rights Reserved.
  20.  *
  21.  * Contributor(s):
  22.  *
  23.  * Alternatively, the contents of this file may be used under the terms of
  24.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  25.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  26.  * in which case the provisions of the GPL or the LGPL are applicable instead
  27.  * of those above. If you wish to allow use of your version of this file only
  28.  * under the terms of either the GPL or the LGPL, and not to allow others to
  29.  * use your version of this file under the terms of the MPL, indicate your
  30.  * decision by deleting the provisions above and replace them with the notice
  31.  * and other provisions required by the GPL or the LGPL. If you do not delete
  32.  * the provisions above, a recipient may use your version of this file under
  33.  * the terms of any one of the MPL, the GPL or the LGPL.
  34.  *
  35.  * ***** END LICENSE BLOCK ***** */
  36. /*
  37.  * The following handles the loading, unloading and management of
  38.  * various PCKS #11 modules
  39.  */
  40.  
  41.  
  42. /*
  43.  * this header file contains routines for parsing PKCS #11 module spec
  44.  * strings. It contains 'C' code and should only be included in one module.
  45.  * Currently it is included in both softoken and the wrapper.
  46.  */
  47. #include <ctype.h>
  48. #include "pkcs11.h"
  49. #include "seccomon.h"
  50. #include "prprf.h"
  51. #include "secmodt.h"
  52. #include "pk11init.h"
  53.  
  54. #define SECMOD_ARG_LIBRARY_PARAMETER "library="
  55. #define SECMOD_ARG_NAME_PARAMETER "name="
  56. #define SECMOD_ARG_MODULE_PARAMETER "parameters="
  57. #define SECMOD_ARG_NSS_PARAMETER "NSS="
  58. #define SECMOD_ARG_FORTEZZA_FLAG "FORTEZZA"
  59. #define SECMOD_ARG_ESCAPE '\\'
  60.  
  61. struct secmodargSlotFlagTable {
  62.     char *name;
  63.     int len;
  64.     unsigned long value;
  65. };
  66.  
  67. #define SECMOD_DEFAULT_CIPHER_ORDER 0
  68. #define SECMOD_DEFAULT_TRUST_ORDER 50
  69.  
  70.  
  71. #define SECMOD_ARG_ENTRY(arg,flag) \
  72. { #arg , sizeof(#arg)-1, flag }
  73. static struct secmodargSlotFlagTable secmod_argSlotFlagTable[] = {
  74.     SECMOD_ARG_ENTRY(RSA,SECMOD_RSA_FLAG),
  75.     SECMOD_ARG_ENTRY(DSA,SECMOD_RSA_FLAG),
  76.     SECMOD_ARG_ENTRY(RC2,SECMOD_RC4_FLAG),
  77.     SECMOD_ARG_ENTRY(RC4,SECMOD_RC2_FLAG),
  78.     SECMOD_ARG_ENTRY(DES,SECMOD_DES_FLAG),
  79.     SECMOD_ARG_ENTRY(DH,SECMOD_DH_FLAG),
  80.     SECMOD_ARG_ENTRY(FORTEZZA,SECMOD_FORTEZZA_FLAG),
  81.     SECMOD_ARG_ENTRY(RC5,SECMOD_RC5_FLAG),
  82.     SECMOD_ARG_ENTRY(SHA1,SECMOD_SHA1_FLAG),
  83.     SECMOD_ARG_ENTRY(MD5,SECMOD_MD5_FLAG),
  84.     SECMOD_ARG_ENTRY(MD2,SECMOD_MD2_FLAG),
  85.     SECMOD_ARG_ENTRY(SSL,SECMOD_SSL_FLAG),
  86.     SECMOD_ARG_ENTRY(TLS,SECMOD_TLS_FLAG),
  87.     SECMOD_ARG_ENTRY(AES,SECMOD_AES_FLAG),
  88.     SECMOD_ARG_ENTRY(PublicCerts,SECMOD_FRIENDLY_FLAG),
  89.     SECMOD_ARG_ENTRY(RANDOM,SECMOD_RANDOM_FLAG),
  90. };
  91.  
  92. #define SECMOD_HANDLE_STRING_ARG(param,target,value,command) \
  93.     if (PORT_Strncasecmp(param,value,sizeof(value)-1) == 0) { \
  94.     param += sizeof(value)-1; \
  95.     target = secmod_argFetchValue(param,&next); \
  96.     param += next; \
  97.     command ;\
  98.     } else  
  99.  
  100. #define SECMOD_HANDLE_FINAL_ARG(param) \
  101.     { param = secmod_argSkipParameter(param); } param = secmod_argStrip(param);
  102.     
  103.  
  104. static int secmod_argSlotFlagTableSize = 
  105.     sizeof(secmod_argSlotFlagTable)/sizeof(secmod_argSlotFlagTable[0]);
  106.  
  107.  
  108. static PRBool secmod_argGetPair(char c) {
  109.     switch (c) {
  110.     case '\'': return c;
  111.     case '\"': return c;
  112.     case '<': return '>';
  113.     case '{': return '}';
  114.     case '[': return ']';
  115.     case '(': return ')';
  116.     default: break;
  117.     }
  118.     return ' ';
  119. }
  120.  
  121. static PRBool secmod_argIsBlank(char c) {
  122.    return isspace(c);
  123. }
  124.  
  125. static PRBool secmod_argIsEscape(char c) {
  126.     return c == '\\';
  127. }
  128.  
  129. static PRBool secmod_argIsQuote(char c) {
  130.     switch (c) {
  131.     case '\'':
  132.     case '\"':
  133.     case '<':
  134.     case '{': /* } end curly to keep vi bracket matching working */
  135.     case '(': /* ) */
  136.     case '[': /* ] */ return PR_TRUE;
  137.     default: break;
  138.     }
  139.     return PR_FALSE;
  140. }
  141.  
  142. static PRBool secmod_argHasChar(char *v, char c)
  143. {
  144.    for ( ;*v; v++) {
  145.     if (*v == c) return PR_TRUE;
  146.    }
  147.    return PR_FALSE;
  148. }
  149.  
  150. static PRBool secmod_argHasBlanks(char *v)
  151. {
  152.    for ( ;*v; v++) {
  153.     if (secmod_argIsBlank(*v)) return PR_TRUE;
  154.    }
  155.    return PR_FALSE;
  156. }
  157.  
  158. static char *secmod_argStrip(char *c) {
  159.    while (*c && secmod_argIsBlank(*c)) c++;
  160.    return c;
  161. }
  162.  
  163. static char *
  164. secmod_argFindEnd(char *string) {
  165.     char endChar = ' ';
  166.     PRBool lastEscape = PR_FALSE;
  167.  
  168.     if (secmod_argIsQuote(*string)) {
  169.     endChar = secmod_argGetPair(*string);
  170.     string++;
  171.     }
  172.  
  173.     for (;*string; string++) {
  174.     if (lastEscape) {
  175.         lastEscape = PR_FALSE;
  176.         continue;
  177.     }
  178.     if (secmod_argIsEscape(*string) && !lastEscape) {
  179.         lastEscape = PR_TRUE;
  180.         continue;
  181.     } 
  182.     if ((endChar == ' ') && secmod_argIsBlank(*string)) break;
  183.     if (*string == endChar) {
  184.         break;
  185.     }
  186.     }
  187.  
  188.     return string;
  189. }
  190.  
  191. static char *
  192. secmod_argFetchValue(char *string, int *pcount)
  193. {
  194.     char *end = secmod_argFindEnd(string);
  195.     char *retString, *copyString;
  196.     PRBool lastEscape = PR_FALSE;
  197.     int len;
  198.  
  199.     len = end - string;
  200.     if (len == 0) {
  201.     *pcount = 0;
  202.     return NULL;
  203.     }
  204.  
  205.     copyString = retString = (char *)PORT_Alloc(len+1);
  206.  
  207.     if (*end) len++;
  208.     *pcount = len;
  209.     if (retString == NULL) return NULL;
  210.  
  211.  
  212.     if (secmod_argIsQuote(*string)) string++;
  213.     for (; string < end; string++) {
  214.     if (secmod_argIsEscape(*string) && !lastEscape) {
  215.         lastEscape = PR_TRUE;
  216.         continue;
  217.     }
  218.     lastEscape = PR_FALSE;
  219.     *copyString++ = *string;
  220.     }
  221.     *copyString = 0;
  222.     return retString;
  223. }
  224.  
  225. static char *
  226. secmod_argSkipParameter(char *string) 
  227. {
  228.      char *end;
  229.      /* look for the end of the <name>= */
  230.      for (;*string; string++) {
  231.     if (*string == '=') { string++; break; }
  232.     if (secmod_argIsBlank(*string)) return(string); 
  233.      }
  234.  
  235.      end = secmod_argFindEnd(string);
  236.      if (*end) end++;
  237.      return end;
  238. }
  239.  
  240.  
  241. static SECStatus
  242. secmod_argParseModuleSpec(char *modulespec, char **lib, char **mod, 
  243.                     char **parameters, char **nss)
  244. {
  245.     int next;
  246.     modulespec = secmod_argStrip(modulespec);
  247.  
  248.     *lib = *mod = *parameters = *nss = 0;
  249.  
  250.     while (*modulespec) {
  251.     SECMOD_HANDLE_STRING_ARG(modulespec,*lib,SECMOD_ARG_LIBRARY_PARAMETER,;)
  252.     SECMOD_HANDLE_STRING_ARG(modulespec,*mod,SECMOD_ARG_NAME_PARAMETER,;)
  253.     SECMOD_HANDLE_STRING_ARG(modulespec,*parameters,
  254.                         SECMOD_ARG_MODULE_PARAMETER,;)
  255.     SECMOD_HANDLE_STRING_ARG(modulespec,*nss,SECMOD_ARG_NSS_PARAMETER,;)
  256.     SECMOD_HANDLE_FINAL_ARG(modulespec)
  257.    }
  258.    return SECSuccess;
  259. }
  260.  
  261.  
  262. static char *
  263. secmod_argGetParamValue(char *paramName,char *parameters)
  264. {
  265.     char searchValue[256];
  266.     int paramLen = strlen(paramName);
  267.     char *returnValue = NULL;
  268.     int next;
  269.  
  270.     if ((parameters == NULL) || (*parameters == 0)) return NULL;
  271.  
  272.     PORT_Assert(paramLen+2 < sizeof(searchValue));
  273.  
  274.     PORT_Strcpy(searchValue,paramName);
  275.     PORT_Strcat(searchValue,"=");
  276.     while (*parameters) {
  277.     if (PORT_Strncasecmp(parameters,searchValue,paramLen+1) == 0) {
  278.         parameters += paramLen+1;
  279.         returnValue = secmod_argFetchValue(parameters,&next);
  280.         break;
  281.     } else {
  282.         parameters = secmod_argSkipParameter(parameters);
  283.     }
  284.     parameters = secmod_argStrip(parameters);
  285.    }
  286.    return returnValue;
  287. }
  288.     
  289.  
  290. static char *
  291. secmod_argNextFlag(char *flags)
  292. {
  293.     for (; *flags ; flags++) {
  294.     if (*flags == ',') {
  295.         flags++;
  296.         break;
  297.     }
  298.     }
  299.     return flags;
  300. }
  301.  
  302. static PRBool
  303. secmod_argHasFlag(char *label, char *flag, char *parameters)
  304. {
  305.     char *flags,*index;
  306.     int len = strlen(flag);
  307.     PRBool found = PR_FALSE;
  308.  
  309.     flags = secmod_argGetParamValue(label,parameters);
  310.     if (flags == NULL) return PR_FALSE;
  311.  
  312.     for (index=flags; *index; index=secmod_argNextFlag(index)) {
  313.     if (PORT_Strncasecmp(index,flag,len) == 0) {
  314.         found=PR_TRUE;
  315.         break;
  316.     }
  317.     }
  318.     PORT_Free(flags);
  319.     return found;
  320. }
  321.  
  322. static void
  323. secmod_argSetNewCipherFlags(unsigned long *newCiphers,char *cipherList)
  324. {
  325.     newCiphers[0] = newCiphers[1] = 0;
  326.     if ((cipherList == NULL) || (*cipherList == 0)) return;
  327.  
  328.     for (;*cipherList; cipherList=secmod_argNextFlag(cipherList)) {
  329.     if (PORT_Strncasecmp(cipherList,SECMOD_ARG_FORTEZZA_FLAG,
  330.                 sizeof(SECMOD_ARG_FORTEZZA_FLAG)-1) == 0) {
  331.         newCiphers[0] |= SECMOD_FORTEZZA_FLAG;
  332.     } 
  333.  
  334.     /* add additional flags here as necessary */
  335.     /* direct bit mapping escape */
  336.     if (*cipherList == 0) {
  337.        if (cipherList[1] == 'l') {
  338.         newCiphers[1] |= atoi(&cipherList[2]);
  339.        } else {
  340.         newCiphers[0] |= atoi(&cipherList[2]);
  341.        }
  342.     }
  343.     }
  344. }
  345.  
  346.  
  347. /*
  348.  * decode a number. handle octal (leading '0'), hex (leading '0x') or decimal
  349.  */
  350. static long
  351. secmod_argDecodeNumber(char *num)
  352. {
  353.     int    radix = 10;
  354.     unsigned long value = 0;
  355.     long retValue = 0;
  356.     int sign = 1;
  357.     int digit;
  358.  
  359.     if (num == NULL) return retValue;
  360.  
  361.     num = secmod_argStrip(num);
  362.  
  363.     if (*num == '-') {
  364.     sign = -1;
  365.     num++;
  366.     }
  367.  
  368.     if (*num == '0') {
  369.     radix = 8;
  370.     num++;
  371.     if ((*num == 'x') || (*num == 'X')) {
  372.         radix = 16;
  373.         num++;
  374.     }
  375.     }
  376.  
  377.    
  378.     for ( ;*num; num++ ) {
  379.     if (isdigit(*num)) {
  380.         digit = *num - '0';
  381.     } else if ((*num >= 'a') && (*num <= 'f'))  {
  382.         digit = *num - 'a' + 10;
  383.     } else if ((*num >= 'A') && (*num <= 'F'))  {
  384.         digit = *num - 'A' + 10;
  385.     } else {
  386.         break;
  387.     }
  388.     if (digit >= radix) break;
  389.     value = value*radix + digit;
  390.     }
  391.  
  392.     retValue = ((int) value) * sign;
  393.     return retValue;
  394. }
  395.  
  396. static long
  397. secmod_argReadLong(char *label,char *params, long defValue, PRBool *isdefault)
  398. {
  399.     char *value;
  400.     long retValue;
  401.     if (isdefault) *isdefault = PR_FALSE; 
  402.  
  403.     value = secmod_argGetParamValue(label,params);
  404.     if (value == NULL) {
  405.     if (isdefault) *isdefault = PR_TRUE;
  406.     return defValue;
  407.     }
  408.     retValue = secmod_argDecodeNumber(value);
  409.     if (value) PORT_Free(value);
  410.  
  411.     return retValue;
  412. }
  413.  
  414.  
  415. static unsigned long
  416. secmod_argSlotFlags(char *label,char *params)
  417. {
  418.     char *flags,*index;
  419.     unsigned long retValue = 0;
  420.     int i;
  421.     PRBool all = PR_FALSE;
  422.  
  423.     flags = secmod_argGetParamValue(label,params);
  424.     if (flags == NULL) return 0;
  425.  
  426.     if (PORT_Strcasecmp(flags,"all") == 0) all = PR_TRUE;
  427.  
  428.     for (index=flags; *index; index=secmod_argNextFlag(index)) {
  429.     for (i=0; i < secmod_argSlotFlagTableSize; i++) {
  430.         if (all || (PORT_Strncasecmp(index, secmod_argSlotFlagTable[i].name,
  431.                 secmod_argSlotFlagTable[i].len) == 0)) {
  432.         retValue |= secmod_argSlotFlagTable[i].value;
  433.         }
  434.     }
  435.     }
  436.     PORT_Free(flags);
  437.     return retValue;
  438. }
  439.  
  440.  
  441. static void
  442. secmod_argDecodeSingleSlotInfo(char *name, char *params, 
  443.                                PK11PreSlotInfo *slotInfo)
  444. {
  445.     char *askpw;
  446.  
  447.     slotInfo->slotID=secmod_argDecodeNumber(name);
  448.     slotInfo->defaultFlags=secmod_argSlotFlags("slotFlags",params);
  449.     slotInfo->timeout=secmod_argReadLong("timeout",params, 0, NULL);
  450.  
  451.     askpw = secmod_argGetParamValue("askpw",params);
  452.     slotInfo->askpw = 0;
  453.  
  454.     if (askpw) {
  455.     if (PORT_Strcasecmp(askpw,"every") == 0) {
  456.             slotInfo->askpw = -1;
  457.     } else if (PORT_Strcasecmp(askpw,"timeout") == 0) {
  458.             slotInfo->askpw = 1;
  459.     } 
  460.     PORT_Free(askpw);
  461.     slotInfo->defaultFlags |= PK11_OWN_PW_DEFAULTS;
  462.     }
  463.     slotInfo->hasRootCerts = secmod_argHasFlag("rootFlags", "hasRootCerts", 
  464.                                                params);
  465.     slotInfo->hasRootTrust = secmod_argHasFlag("rootFlags", "hasRootTrust", 
  466.                                                params);
  467. }
  468.  
  469. static char *
  470. secmod_argGetName(char *inString, int *next) 
  471. {
  472.     char *name=NULL;
  473.     char *string;
  474.     int len;
  475.  
  476.     /* look for the end of the <name>= */
  477.     for (string = inString;*string; string++) {
  478.     if (*string == '=') { break; }
  479.     if (secmod_argIsBlank(*string)) break;
  480.     }
  481.  
  482.     len = string - inString;
  483.  
  484.     *next = len; 
  485.     if (*string == '=') (*next) += 1;
  486.     if (len > 0) {
  487.     name = PORT_Alloc(len+1);
  488.     PORT_Strncpy(name,inString,len);
  489.     name[len] = 0;
  490.     }
  491.     return name;
  492. }
  493.  
  494. static PK11PreSlotInfo *
  495. secmod_argParseSlotInfo(PRArenaPool *arena, char *slotParams, int *retCount)
  496. {
  497.     char *slotIndex;
  498.     PK11PreSlotInfo *slotInfo = NULL;
  499.     int i=0,count = 0,next;
  500.  
  501.     *retCount = 0;
  502.     if ((slotParams == NULL) || (*slotParams == 0))  return NULL;
  503.  
  504.     /* first count the number of slots */
  505.     for (slotIndex = secmod_argStrip(slotParams); *slotIndex; 
  506.      slotIndex = secmod_argStrip(secmod_argSkipParameter(slotIndex))) {
  507.     count++;
  508.     }
  509.  
  510.     /* get the data structures */
  511.     if (arena) {
  512.     slotInfo = (PK11PreSlotInfo *) 
  513.             PORT_ArenaAlloc(arena,count*sizeof(PK11PreSlotInfo));
  514.     PORT_Memset(slotInfo,0,count*sizeof(PK11PreSlotInfo));
  515.     } else {
  516.     slotInfo = (PK11PreSlotInfo *) 
  517.             PORT_ZAlloc(count*sizeof(PK11PreSlotInfo));
  518.     }
  519.     if (slotInfo == NULL) return NULL;
  520.  
  521.     for (slotIndex = secmod_argStrip(slotParams), i = 0; 
  522.                     *slotIndex && i < count ; ) {
  523.     char *name;
  524.     name = secmod_argGetName(slotIndex,&next);
  525.     slotIndex += next;
  526.  
  527.     if (!secmod_argIsBlank(*slotIndex)) {
  528.         char *args = secmod_argFetchValue(slotIndex,&next);
  529.         slotIndex += next;
  530.         if (args) {
  531.         secmod_argDecodeSingleSlotInfo(name,args,&slotInfo[i]);
  532.         i++;
  533.         PORT_Free(args);
  534.         }
  535.     }
  536.     if (name) PORT_Free(name);
  537.     slotIndex = secmod_argStrip(slotIndex);
  538.     }
  539.     *retCount = i;
  540.     return slotInfo;
  541. }
  542.  
  543. static char *secmod_nullString = "";
  544.  
  545. static char *
  546. secmod_formatValue(PRArenaPool *arena, char *value, char quote)
  547. {
  548.     char *vp,*vp2,*retval;
  549.     int size = 0, escapes = 0;
  550.  
  551.     for (vp=value; *vp ;vp++) {
  552.     if ((*vp == quote) || (*vp == SECMOD_ARG_ESCAPE)) escapes++;
  553.     size++;
  554.     }
  555.     if (arena) {
  556.     retval = PORT_ArenaZAlloc(arena,size+escapes+1);
  557.     } else {
  558.     retval = PORT_ZAlloc(size+escapes+1);
  559.     }
  560.     if (retval == NULL) return NULL;
  561.     vp2 = retval;
  562.     for (vp=value; *vp; vp++) {
  563.     if ((*vp == quote) || (*vp == SECMOD_ARG_ESCAPE)) 
  564.                 *vp2++ = SECMOD_ARG_ESCAPE;
  565.     *vp2++ = *vp;
  566.     }
  567.     return retval;
  568. }
  569.     
  570. static char *secmod_formatPair(char *name,char *value, char quote)
  571. {
  572.     char openQuote = quote;
  573.     char closeQuote = secmod_argGetPair(quote);
  574.     char *newValue = NULL;
  575.     char *returnValue;
  576.     PRBool need_quote = PR_FALSE;
  577.  
  578.     if (!value || (*value == 0)) return secmod_nullString;
  579.  
  580.     if (secmod_argHasBlanks(value) || secmod_argIsQuote(value[0]))
  581.                              need_quote=PR_TRUE;
  582.  
  583.     if ((need_quote && secmod_argHasChar(value,closeQuote))
  584.                  || secmod_argHasChar(value,SECMOD_ARG_ESCAPE)) {
  585.     value = newValue = secmod_formatValue(NULL, value,quote);
  586.     if (newValue == NULL) return secmod_nullString;
  587.     }
  588.     if (need_quote) {
  589.         returnValue = PR_smprintf("%s=%c%s%c",name,openQuote,value,closeQuote);
  590.     } else {
  591.         returnValue = PR_smprintf("%s=%s",name,value);
  592.     }
  593.     if (returnValue == NULL) returnValue = secmod_nullString;
  594.  
  595.     if (newValue) PORT_Free(newValue);
  596.  
  597.     return returnValue;
  598. }
  599.  
  600. static char *secmod_formatIntPair(char *name, unsigned long value, 
  601.                                   unsigned long def)
  602. {
  603.     char *returnValue;
  604.  
  605.     if (value == def) return secmod_nullString;
  606.  
  607.     returnValue = PR_smprintf("%s=%d",name,value);
  608.  
  609.     return returnValue;
  610. }
  611.  
  612. static void
  613. secmod_freePair(char *pair)
  614. {
  615.     if (pair && pair != secmod_nullString) {
  616.     PR_smprintf_free(pair);
  617.     }
  618. }
  619.  
  620. #define MAX_FLAG_SIZE  sizeof("internal")+sizeof("FIPS")+sizeof("moduleDB")+\
  621.                 sizeof("moduleDBOnly")+sizeof("critical")
  622. static char *
  623. secmod_mkNSSFlags(PRBool internal, PRBool isFIPS,
  624.         PRBool isModuleDB, PRBool isModuleDBOnly, PRBool isCritical)
  625. {
  626.     char *flags = (char *)PORT_ZAlloc(MAX_FLAG_SIZE);
  627.     PRBool first = PR_TRUE;
  628.  
  629.     PORT_Memset(flags,0,MAX_FLAG_SIZE);
  630.     if (internal) {
  631.     PORT_Strcat(flags,"internal");
  632.     first = PR_FALSE;
  633.     }
  634.     if (isFIPS) {
  635.     if (!first) PORT_Strcat(flags,",");
  636.     PORT_Strcat(flags,"FIPS");
  637.     first = PR_FALSE;
  638.     }
  639.     if (isModuleDB) {
  640.     if (!first) PORT_Strcat(flags,",");
  641.     PORT_Strcat(flags,"moduleDB");
  642.     first = PR_FALSE;
  643.     }
  644.     if (isModuleDBOnly) {
  645.     if (!first) PORT_Strcat(flags,",");
  646.     PORT_Strcat(flags,"moduleDBOnly");
  647.     first = PR_FALSE;
  648.     }
  649.     if (isCritical) {
  650.     if (!first) PORT_Strcat(flags,",");
  651.     PORT_Strcat(flags,"critical");
  652.     first = PR_FALSE;
  653.     }
  654.     return flags;
  655. }
  656.  
  657. static char *
  658. secmod_mkCipherFlags(unsigned long ssl0, unsigned long ssl1)
  659. {
  660.     char *cipher = NULL;
  661.     int i;
  662.  
  663.     for (i=0; i < sizeof(ssl0)*8; i++) {
  664.     if (ssl0 & (1<<i)) {
  665.         char *string;
  666.         if ((1<<i) == SECMOD_FORTEZZA_FLAG) {
  667.         string = PR_smprintf("%s","FORTEZZA");
  668.         } else {
  669.         string = PR_smprintf("0h0x%08x",1<<i);
  670.         }
  671.         if (cipher) {
  672.         char *tmp;
  673.         tmp = PR_smprintf("%s,%s",cipher,string);
  674.         PR_smprintf_free(cipher);
  675.         PR_smprintf_free(string);
  676.         cipher = tmp;
  677.         } else {
  678.         cipher = string;
  679.         }
  680.     }
  681.     }
  682.     for (i=0; i < sizeof(ssl0)*8; i++) {
  683.     if (ssl1 & (1<<i)) {
  684.         if (cipher) {
  685.         char *tmp;
  686.         tmp = PR_smprintf("%s,0l0x%08x",cipher,1<<i);
  687.         PR_smprintf_free(cipher);
  688.         cipher = tmp;
  689.         } else {
  690.         cipher = PR_smprintf("0l0x%08x",1<<i);
  691.         }
  692.     }
  693.     }
  694.  
  695.     return cipher;
  696. }
  697.  
  698. static char *
  699. secmod_mkSlotFlags(unsigned long defaultFlags)
  700. {
  701.     char *flags=NULL;
  702.     int i,j;
  703.  
  704.     for (i=0; i < sizeof(defaultFlags)*8; i++) {
  705.     if (defaultFlags & (1<<i)) {
  706.         char *string = NULL;
  707.  
  708.         for (j=0; j < secmod_argSlotFlagTableSize; j++) {
  709.         if (secmod_argSlotFlagTable[j].value == ( 1UL << i )) {
  710.             string = secmod_argSlotFlagTable[j].name;
  711.             break;
  712.         }
  713.         }
  714.         if (string) {
  715.         if (flags) {
  716.             char *tmp;
  717.             tmp = PR_smprintf("%s,%s",flags,string);
  718.             PR_smprintf_free(flags);
  719.             flags = tmp;
  720.         } else {
  721.             flags = PR_smprintf("%s",string);
  722.         }
  723.         }
  724.     }
  725.     }
  726.  
  727.     return flags;
  728. }
  729.  
  730. #define SECMOD_MAX_ROOT_FLAG_SIZE  sizeof("hasRootCerts")+sizeof("hasRootTrust")
  731.  
  732. static char *
  733. secmod_mkRootFlags(PRBool hasRootCerts, PRBool hasRootTrust)
  734. {
  735.     char *flags= (char *)PORT_ZAlloc(SECMOD_MAX_ROOT_FLAG_SIZE);
  736.     PRBool first = PR_TRUE;
  737.  
  738.     PORT_Memset(flags,0,SECMOD_MAX_ROOT_FLAG_SIZE);
  739.     if (hasRootCerts) {
  740.     PORT_Strcat(flags,"hasRootCerts");
  741.     first = PR_FALSE;
  742.     }
  743.     if (hasRootTrust) {
  744.     if (!first) PORT_Strcat(flags,",");
  745.     PORT_Strcat(flags,"hasRootTrust");
  746.     first = PR_FALSE;
  747.     }
  748.     return flags;
  749. }
  750.  
  751. static char *
  752. secmod_mkSlotString(unsigned long slotID, unsigned long defaultFlags,
  753.           unsigned long timeout, unsigned char askpw_in,
  754.           PRBool hasRootCerts, PRBool hasRootTrust) {
  755.     char *askpw,*flags,*rootFlags,*slotString;
  756.     char *flagPair,*rootFlagsPair;
  757.     
  758.     switch (askpw_in) {
  759.     case 0xff:
  760.     askpw = "every";
  761.     break;
  762.     case 1:
  763.     askpw = "timeout";
  764.     break;
  765.     default:
  766.     askpw = "any";
  767.     break;
  768.     }
  769.     flags = secmod_mkSlotFlags(defaultFlags);
  770.     rootFlags = secmod_mkRootFlags(hasRootCerts,hasRootTrust);
  771.     flagPair=secmod_formatPair("slotFlags",flags,'\'');
  772.     rootFlagsPair=secmod_formatPair("rootFlags",rootFlags,'\'');
  773.     if (flags) PR_smprintf_free(flags);
  774.     if (rootFlags) PORT_Free(rootFlags);
  775.     if (defaultFlags & PK11_OWN_PW_DEFAULTS) {
  776.         slotString = PR_smprintf("0x%08lx=[%s askpw=%s timeout=%d %s]",
  777.                 (PRUint32)slotID,flagPair,askpw,timeout,
  778.                 rootFlagsPair);
  779.     } else {
  780.         slotString = PR_smprintf("0x%08lx=[%s %s]",
  781.                 (PRUint32)slotID,flagPair,rootFlagsPair);
  782.     }
  783.     secmod_freePair(flagPair);
  784.     secmod_freePair(rootFlagsPair);
  785.     return slotString;
  786. }
  787.  
  788. static char *
  789. secmod_mkNSS(char **slotStrings, int slotCount, PRBool internal, PRBool isFIPS,
  790.       PRBool isModuleDB,  PRBool isModuleDBOnly, PRBool isCritical, 
  791.       unsigned long trustOrder, unsigned long cipherOrder,
  792.                 unsigned long ssl0, unsigned long ssl1) {
  793.     int slotLen, i;
  794.     char *slotParams, *ciphers, *nss, *nssFlags, *tmp;
  795.     char *trustOrderPair,*cipherOrderPair,*slotPair,*cipherPair,*flagPair;
  796.  
  797.  
  798.     /* now let's build up the string
  799.      * first the slot infos
  800.      */
  801.     slotLen=0;
  802.     for (i=0; i < (int)slotCount; i++) {
  803.     slotLen += PORT_Strlen(slotStrings[i])+1;
  804.     }
  805.     slotLen += 1; /* space for the final NULL */
  806.  
  807.     slotParams = (char *)PORT_ZAlloc(slotLen);
  808.     PORT_Memset(slotParams,0,slotLen);
  809.     for (i=0; i < (int)slotCount; i++) {
  810.     PORT_Strcat(slotParams,slotStrings[i]);
  811.     PORT_Strcat(slotParams," ");
  812.     PR_smprintf_free(slotStrings[i]);
  813.     slotStrings[i]=NULL;
  814.     }
  815.     
  816.     /*
  817.      * now the NSS structure
  818.      */
  819.     nssFlags = secmod_mkNSSFlags(internal,isFIPS,isModuleDB,isModuleDBOnly,
  820.                             isCritical); 
  821.     /* for now only the internal module is critical */
  822.     ciphers = secmod_mkCipherFlags(ssl0, ssl1);
  823.  
  824.     trustOrderPair=secmod_formatIntPair("trustOrder",trustOrder,
  825.                     SECMOD_DEFAULT_TRUST_ORDER);
  826.     cipherOrderPair=secmod_formatIntPair("cipherOrder",cipherOrder,
  827.                     SECMOD_DEFAULT_CIPHER_ORDER);
  828.     slotPair=secmod_formatPair("slotParams",slotParams,'{'); /* } */
  829.     if (slotParams) PORT_Free(slotParams);
  830.     cipherPair=secmod_formatPair("ciphers",ciphers,'\'');
  831.     if (ciphers) PR_smprintf_free(ciphers);
  832.     flagPair=secmod_formatPair("Flags",nssFlags,'\'');
  833.     if (nssFlags) PORT_Free(nssFlags);
  834.     nss = PR_smprintf("%s %s %s %s %s",trustOrderPair,
  835.             cipherOrderPair,slotPair,cipherPair,flagPair);
  836.     secmod_freePair(trustOrderPair);
  837.     secmod_freePair(cipherOrderPair);
  838.     secmod_freePair(slotPair);
  839.     secmod_freePair(cipherPair);
  840.     secmod_freePair(flagPair);
  841.     tmp = secmod_argStrip(nss);
  842.     if (*tmp == '\0') {
  843.     PR_smprintf_free(nss);
  844.     nss = NULL;
  845.     }
  846.     return nss;
  847. }
  848.  
  849. static char *
  850. secmod_mkNewModuleSpec(char *dllName, char *commonName, char *parameters, 
  851.                                 char *NSS) {
  852.     char *moduleSpec;
  853.     char *lib,*name,*param,*nss;
  854.  
  855.     /*
  856.      * now the final spec
  857.      */
  858.     lib = secmod_formatPair("library",dllName,'\"');
  859.     name = secmod_formatPair("name",commonName,'\"');
  860.     param = secmod_formatPair("parameters",parameters,'\"');
  861.     nss = secmod_formatPair("NSS",NSS,'\"');
  862.     moduleSpec = PR_smprintf("%s %s %s %s", lib,name,param,nss);
  863.     secmod_freePair(lib);
  864.     secmod_freePair(name);
  865.     secmod_freePair(param);
  866.     secmod_freePair(nss);
  867.     return (moduleSpec);
  868. }
  869.  
  870.